import getLastEvent from '../utils/getLastEvent'
import getSelector from '../utils/getSelector'

export function getLines(stack) {
    // "TypeError: Cannot read property 'key' of undefined
    // at triggerJsError (http://localhost:8080/:15:42)
    // at HTMLButtonElement.onclick (http://localhost:8080/:10:60)"
    // --> 
    // triggerJsError (http://localhost:8080/:15:42)^HTMLButtonElement.onclick (http://localhost:8080/:10:60)
    return stack
        .split('\n')
        .slice(1)
        .map(item => item.replace(/^\s+at\s+/g, ""))
        .join('^')
}

export function injectJsError() {
    window.addEventListener('error', function (event) {
        console.log(event)
        let lastEvent = getLastEvent() // 最后一个交互事件
        // 资源文件加载错误
        if (event.target && (event.target.href || event.target.src)) {
            let log = {
                kind: 'stability',
                type: 'error',
                errorType: 'resourceError', // 资源文件加载错误
                filename: event.target.href || event.target.src, // 错误文件
                tagName: event.target.tagName, // 错误标签 script link
                selector: getSelector(event.target) // 最后一个操作的元素
            }
            console.log('resourceError---log', log)
        } else {
            // js 执行出错
            let log = {
                kind: 'stability', // 监控指标的大类
                type: 'error', // 小类型 错误
                errorType: 'jsError', // 执行js出错
                message: event.message, // 错误信息
                filename: event.filename, // 错误文件
                position: `${event.lineno}:${event.colno}`, // 错误代码位置 行:列
                stack: getLines(event.error.stack), // 错误堆栈信息
                selector: lastEvent ? getSelector(lastEvent.path) : '' // 最后一个操作的元素
            }
            console.log('jsError---log', log)
        }
    }, true) // 捕获模式

    // 监听 promise 未被 catch 的错误
    window.addEventListener('unhandledrejection', function(event) {
        console.log('unhandledrejection', event)
        let lastEvent = getLastEvent() // 最后一个交互事件
        let filename = ''
        let lineno = 0
        let colno = 0
        let stack = ''
        let message = ''
        let reason = event.reason
        if (typeof reason === 'string') {
            message = reason
        } else if (typeof reason === 'object') { // 说明错误是一个对象
            message = reason.message

            if (reason.stack) {
                // TypeError: Cannot read property 'key' of undefined
                // at http://localhost:8080/:24:34  行:列
                // at new Promise (<anonymous>)
                // at triggerPromiseError (http://localhost:8080/:22:13)
                // at HTMLButtonElement.onclick (http://localhost:8080/:13:65)"
                let matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/)
                filename = matchResult[1]
                lineno = matchResult[1]
                colno = matchResult[1]

                stack = getLines(reason.stack)
            }
        }

        let log = {
            kind: 'stability',
            type: 'error',
            errorType: 'promiseError',
            message, // 报错信息
            filename, // 报错文件
            position: `${lineno}:${colno}`, // 报错文职
            stack, // 调用栈信息
            selector: lastEvent ? getSelector(lastEvent.path) : '' // 最后一个调用的元素
        }

        console.log('promiseError-log', log)
    })
}